﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Text;
using Labthink.PCSoft.UniversalHost4.Model;
using Labthink.PCSoft.UniversalHost4.Model.User;
using Labthink.PCSoft.UniversalHost4.Utility;
using NLog;

namespace Labthink.PCSoft.UniversalHost4.DataAccess
{
    public class LogRepository : BaseRepository
    {
        private static readonly Logger Log = LogManager.GetCurrentClassLogger();

        public static UserInfo CurrentUser { get; set; }

        /// <summary>
        /// 记录一条操作日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="opType"></param>
        /// <returns></returns>
        public static int AddLog(string content, string opType)
        {
            return AddLog(content, opType, CurrentUser.LoginName, CurrentUser.UserName);
        }

        /// <summary>
        /// 记录一条操作日志
        /// </summary>
        /// <param name="log"></param>
        /// <returns></returns>
        public static int AddLog(OperateLog log)
        {
            return AddLog(log.Content, log.OpType, CurrentUser.LoginName, CurrentUser.UserName);
        }

        /// <summary>
        /// 记录一条操作日志
        /// </summary>
        /// <param name="content"></param>
        /// <param name="opType"></param>
        /// <param name="loginName"></param>
        /// <param name="userName"></param>
        /// <returns></returns>
        public static int AddLog(string content, string opType, string loginName, string userName)
        {
            IsDbExist();
            Log.Debug("{0}({1})记录操作日志:{2}", loginName, userName, content);
            const string sql =
                "INSERT INTO OperateLog (IPAddress,LoginName,UserName,OpType,Content,LogTime) VALUES (@IPAddress,@LoginName,@UserName,@OpType,@Content,@LogTime)";
            try
            {
                return SqliteHelper.ExecuteNonQuery(OperationLogDb, sql, "", loginName, userName, opType, content, DateTime.Now);
            }
            catch (Exception e)
            {
                Log.Error("添加操作日志失败:{0}", e, sql);
                return -1;
            }
        }

        /// <summary>
        /// 获取操作日志
        /// </summary>
        /// <param name="user"></param>
        /// <param name="isAdmin"></param>
        /// <param name="opType"></param>
        /// <param name="end"></param>
        /// <param name="content"></param>
        /// <param name="pageNum">当前页数</param>
        /// <param name="pageCount">每页多少条记录</param>
        /// <param name="start"></param>
        /// <returns></returns>
        public static PagedList<OperateLog> GetLogs(string user, bool isAdmin, string opType, DateTime start, DateTime end, string content, int pageNum, int pageCount)
        {
            IsDbExist();
            Log.Debug("查询第{0}页{1}条操作日志记录", pageNum, pageCount);
            var logs = new List<OperateLog>();
            if (pageNum == 0) pageNum = 1;
            if (pageNum <= 0 || pageCount <= 0)
            {
                return null;
            }

            var objs = new List<object>();
            var sqlData = new StringBuilder("SELECT * FROM OperateLog WHERE 1=1");
            var sqlCount = new StringBuilder("SELECT COUNT(1) FROM OperateLog WHERE 1=1");

            if (!string.IsNullOrEmpty(user))
            {
                if (!isAdmin)
                {
                    sqlData.Append(" AND LoginName=@User ");
                    sqlCount.Append(" AND LoginName=@User");
                    objs.Add(user);
                }
                else
                {
                    sqlData.Append(" AND (LoginName LIKE @User OR UserName LIKE @User)");
                    sqlCount.Append(" AND (LoginName LIKE @User OR UserName LIKE @User)");
                    objs.Add("%" + user + "%");
                    objs.Add("%" + user + "%");
                }
            }

            if (!string.IsNullOrEmpty(opType))
            {
                sqlData.Append(" AND OpType LIKE @OpType");
                sqlCount.Append(" AND OpType LIKE @OpType");
                objs.Add("%" + opType + "%");
            }

            if (!string.IsNullOrEmpty(content))
            {
                sqlData.Append(" AND Content LIKE @Content");
                sqlCount.Append(" AND Content LIKE @Content");
                objs.Add("%" + content + "%");
            }

            sqlData.Append(" AND LogTime>=@StartTime AND LogTime <=@endTime ORDER BY Id DESC");
            sqlCount.Append(" AND LogTime>=@StartTime AND LogTime <=@endTime");
            objs.Add(DateTime.Parse(start.ToString("yyyy-MM-dd") + " 00:00:00"));
            objs.Add(DateTime.Parse(end.ToString("yyyy-MM-dd") + " 23:59:59"));
            sqlData.Append(" LIMIT " + (pageNum - 1) * pageCount + "," + pageCount);
            int count = 0;
            var con = new SQLiteConnection(SqliteHelper.CreateConnectionString(OperationLogDb));
            con.Open();
            using (var cmd = con.CreateCommand())
            {
                try
                {
                    var reader = SqliteHelper.ExecuteReader(cmd, sqlData.ToString(), objs.ToArray());
                    while (reader.Read())
                    {
                        logs.Add(new OperateLog
                        {
                            Id = reader["Id"].ToInt32(),
                            Content = reader["Content"].ToString(),
                            IpAddress = reader["IpAddress"].ToString(),
                            LoginName = reader["LoginName"].ToString(),
                            OpType = reader["OpType"].ToString(),
                            UserName = reader["UserName"].ToString(),
                            LogTime = reader["LogTime"].ToDateTime()
                        });
                    }
                    reader.Close();
                }
                catch (Exception e)
                {
                    Log.Error("查询操作日志出错:{0}", e, sqlData.ToString());
                    return null;
                }
            }

            if (con.State != ConnectionState.Open) con.Open();
            try
            {
                count = SqliteHelper.ExecuteScalar(OperationLogDb, sqlCount.ToString(), objs.ToArray()).ToInt32();
            }
            catch (Exception e)
            {
                Log.Error("获取操作日志总数出错:{0}", e, sqlCount.ToString());
                return null;
            }

            return new PagedList<OperateLog>(logs)
            {
                TotalCount = count,
                PageIndex = pageNum,
                PageSize = logs.Count,
                PageCount = (int)Math.Ceiling((double)count / pageCount)
            };
        }
    }
}
